<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>建造者模式(生成器模式)-链式操作</title>
</head>

<body>

</body>
<script>
    // 建造者链式操作

    // 总结：
        // 1.Director：指挥者，调用建造者中的部件具体实现进行部件装配，相当于整车组装厂，最终返回装配完毕的产品。
        // 2.Builder： 建造者，含有不同部件的生产方式给指挥者调用，是部件真正的生产者，但没有部件的装配流程。
        // 3.Product：产品，要返回给访问者的复杂对象。
    
    // tip:如果希望扩展实例的功能，那么只需要在建造者类的原型上增加一个实例方法，再返回 this 即可。

    // 链式操作原理
    // 当一个函数被调用的时候，当前的this 指向的是被调用的这个函数（ES6 的箭头函数除外）
    // 当一个对象或者实例下有多个方法，通过对象或者实例去调用他自己的方法时，当前的this 指向的是 当前的这个对象或者实例，
    // 如果在这个方法执行完成以后，返回 this
    // 其实也就等于返回的是当前的对象或者实例，在返回的这个对象或者实例 的基础上再去调用这个对象或者实例下的其他方法
    // 就可以省去重新拿当前对象或者实例的步骤，就可以再上一个方法后边继续调用其他方法。链式调用就可以形成。


    class AirplaneBuilder {
        constructor({ color = 'black', weight = '14000KG' }) {
            this.color = color
            this.weight = weight
        }
        selectPower(type) {
            const powerSystem = {}
            switch (type) {
                case 'small':
                    powerSystem.powerType = '飞燕动力系统'
                    powerSystem.powerIntro = '正在使用飞燕动力系统'
                    break
                case 'normal':
                    powerSystem.powerType = '雷鹰动力系统'
                    powerSystem.powerIntro = '正在使用雷鹰动力系统'
                    break
                case 'big':
                    powerSystem.powerType = '麦克斯动力系统'
                    powerSystem.powerIntro = '正在使用麦克斯动力系统'
                    break
            }
            this.powerSystem = powerSystem
            return this
        }
        selectTroops(type) {
            const troops = {}
            switch (type) {
                case 'TPC':
                    troops.troopsType = '远东总部'
                    troops.commander = '居间惠'
                    break
                case 'STPC':
                    troops.troopsType = '东南分部'
                    troops.commander = '喜比'
                    break
                case 'KST':
                    troops.troopsType = '西北分部'
                    troops.commander = '辰东'
                    break
            }
            this.troops = troops
            return this
        }
    }
    class AirplaneMaker {
        constructor(params, power, troops) {
            // 链式建造
            const plane = new AirplaneBuilder(params).selectPower(power).selectTroops(troops)
            return plane
        }
    }

    let feiyan = new AirplaneMaker({ color: 'white', weight: '18520KG' }, 'big', 'TPC')
    console.log(feiyan)

</script>

</html>